package com.wrupple.muba.widget.client.widgets.panels;

import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.layout.client.Layout.AnimationCallback;
import com.google.gwt.layout.client.Layout.Layer;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.LayoutPanel;
import com.google.gwt.user.client.ui.ResizeComposite;
import com.google.gwt.user.client.ui.Widget;
import com.wrupple.muba.util.client.SlidingDialog;
import com.wrupple.muba.util.client.api.transition.FadingTransition;

public class TransitionPanel extends ResizeComposite implements AcceptsOneWidget {

	class RemoveCurrentAndSetNew implements AnimationCallback {
		private IsWidget next;

		protected RemoveCurrentAndSetNew(IsWidget next) {
			super();
			this.next = next;
		}

		@Override
		public void onAnimationComplete() {
			if (current != null) {
				current.removeFromParent();
				current = null;
			}
			if(main.getWidgetCount()>1){
				for(Widget w:main){
					if(w!=next){
						main.remove(w);
					}
				}
			}
			setCurrent(next);
		}

		@Override
		public void onLayout(Layer layer, double progress) {
		}

	}

	protected LayoutPanel main;
	private Widget current;
	
	

	protected TransitionPanel() {
		this(new LayoutPanel());
	}

	public TransitionPanel(LayoutPanel layoutPanel) {
		super();
		this.main = layoutPanel;
		initWidget(main);
	}

	@Override
	public void setWidget(IsWidget w) {
		if(w==null){
			main.clear();
			return;
		}
		if(w==current){
			//do nothing
		}else{
			if (main.getWidgetCount() == 0) {
				// firstwidget
				main.add(w);
				softTransition(w);
			} else if (main.getWidgetIndex(w.asWidget()) < 0) {
				if(main.getWidgetIndex(current)<0){
					current=null;
					// firstwidget
					main.add(w);
					softTransition(w);
				}else{
					// new widget
					main.add(w);
					transitionFromBack(w);
				}
				
			} else {
				// widget is contained this only happends when someone added the widget without using this method
				transitionFromFront(w);
				
			}
		}
		
	}
	
	public void setWidgetFromFront(IsWidget w){
		prepareTransition(w.asWidget());
		setWidget(w);
	}

	private void transitionFromFront(IsWidget next) {
		LayoutPanel container = main;

		AnimationCallback callback = new RemoveCurrentAndSetNew(next);
		if (LocaleInfo.getCurrentLocale().isRTL()) {
			SlidingDialog.slideFromLeft(container, next.asWidget(), current, 100).animate(500, callback);
		} else {
			SlidingDialog.slideFromRight(container, next.asWidget(), current, 100).animate(500, callback);
		}
	}

	private void transitionFromBack(IsWidget next) {
		LayoutPanel container = main;
		AnimationCallback callback = new RemoveCurrentAndSetNew(next);
		if (LocaleInfo.getCurrentLocale().isRTL()) {
			SlidingDialog.slideFromRight(container, next.asWidget(), current, 100).animate(500, callback);
		} else {
			SlidingDialog.slideFromLeft(container, next.asWidget(), current, 100).animate(500, callback);
		}

	}

	private void softTransition(IsWidget next) {
		AnimationCallback callback = new RemoveCurrentAndSetNew(next);
		FadingTransition.fade(next, null, callback).run(500);
	}


	private void setCurrent(IsWidget current) {
		this.current = current.asWidget();
	}

	public Widget getCurrentWidget() {
		return current;
	}

	private void prepareTransition(Widget widget) {
		main.add(widget);
		main.setWidgetLeftWidth(widget, 0, Unit.PX, 0, Unit.PX);
		main.forceLayout();
	}

	public void clear() {
		main.clear();
	}

}
